package com.ruyuan.seckilling.activity.schedule;

import com.alibaba.fastjson.JSON;
import com.ruyuan.seckilling.activity.constant.ActivityStatusVal;
import com.ruyuan.seckilling.activity.entity.Activity;
import com.ruyuan.seckilling.activity.entity.ActivitySkuRef;
import com.ruyuan.seckilling.activity.service.ActivityService;
import com.ruyuan.seckilling.activity.service.ActivitySkuRefService;
import com.ruyuan.seckilling.common.CacheKey;
import com.ruyuan.seckilling.inventory.api.InventoryApi;
import com.ruyuan.seckilling.inventory.vo.CleanStockRequest;
import com.ruyuan.seckilling.inventory.vo.ProductStockVo;
import com.ruyuan.seckilling.inventory.vo.SyncProductStockRequest;
import com.ruyuan.starter.jedis.LockService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @author zhonghuashishan
 */
@Slf4j
@Component
public class CleanDataTask {

    @Autowired
    private ActivityService activityService;

    @Autowired
    private ActivitySkuRefService activitySkuRefService;

    @Autowired
    private LockService lockService;

    @Autowired
    private InventoryApi inventoryApi;

    @Scheduled(fixedDelay = 10_000)
    public void run() {
        String lockToken = lockService.tryLock(CacheKey.CLEAN_DATA_LOCK, 1, TimeUnit.SECONDS);
        if (lockToken == null) {
            return;
        }
        log.info("秒杀活动结束之后请清理数据，获取分布式锁成功, lockToken={}", lockToken);
        try {
            // 查询已经结束1小时的秒杀活动
            List<Activity> activities = activityService.queryListForCleanDataTask();
            if (CollectionUtils.isEmpty(activities)) {
                return;
            }

            for (Activity activity : activities) {
                List<ActivitySkuRef> activitySkuRefs = activitySkuRefService.queryByActivityId(activity.getId());
                if (CollectionUtils.isEmpty(activitySkuRefs)) {
                    continue;
                }

                // 清理库存
                List<Long> skuIds = activitySkuRefs.stream().map(ActivitySkuRef::getSkuId).collect(Collectors.toList());
                CleanStockRequest request = CleanStockRequest.builder().activityId(activity.getId()).skuIds(skuIds).build();
                List<ProductStockVo> productStockVos = inventoryApi.cleanStock(request);

                // 把此时的库存状态保存到数据库中
                for (ProductStockVo vo : productStockVos) {
                    activitySkuRefService.modify(vo.getActivityId(), vo.getSkuId(),
                            vo.getSalableStock(), vo.getLockedStock(), vo.getSaledStock());
                    log.info("秒杀活动结束之后请清理数据，保存库存信息, stock={}", JSON.toJSONString(vo));
                }

                // 修改秒杀活动状态
                activityService.updataStatus(activity.getId(), ActivityStatusVal.INVENTORY_SYNCED.getCode(),
                        ActivityStatusVal.DATA_CLEANED.getCode());
            }
        } finally {
            lockService.release(CacheKey.TRIGGER_STOCK_LOCK, lockToken);
            log.info("秒杀活动结束之后请清理数据，释放分布式锁");
        }
    }
}
